/*
 * Created 02-sept-2005.
 */
package moon.metrics.concretemetrics;

import java.util.List;

import moon.core.NamedObject;
import moon.core.classdef.ClassDef;
import moon.core.classdef.NameSpace;
import moon.metrics.core.Measure;
import moon.metrics.core.SystemMetric;
/**
 * Number Of Abstract Types per each package (NOTa/NOTc).
 * @author Estrella Resa Camarero and Laura Moneo Sanz
 * @version 1.0
 * @since JavaMOON 1.3
 * @see MOONMetric
 */
public class Abs extends SystemMetric {

	/**
	 * Constructs a Abs metric.
	 *
	 * @param name         name
	 * @param description  description
	 * @param valueMin     minimum value
	 * @param valueMax     maximum value
	 */
	public Abs(String name, String description, float valueMin, float valueMax) {
		super(name, description, valueMin, valueMax);
	}

	/**
	 * Constructs a Abs metric.
	 * 
	 * @param name name
	 * @param description description
	 * @param author author
	 * @param year year
	 * @param valueMin minimum value
	 * @param valueMax maximum value
	 */
	public Abs(String name, String description, String author, int year,
			float valueMin, float valueMax) {
		super(name, description, author, year, valueMin, valueMax);
	}

	/**
	 * Calculates the number of abstract classes and interfaces in each package (NOTa/NOTc).
	 * 
	 * @param namedObject object to measure
	 * @return  measure
	 */
	public Measure run(NamedObject namedObject) {
		
		NameSpace ns = (NameSpace) namedObject;
		
		float value = abstractness (ns);
		Measure m = new Measure(value, ns, this);
		
		return m;
	}
	
	/**
	 * Solution to count the number of abstract classes and interfaces in each package.
	 *  
	 * @param ns package
	 * @return number of abstract classes and interfaces in each package
	 */
	private float abstractness (NameSpace ns){
		float abstClass = 0.0F;
		float classes = 0.0F;

		List<ClassDef> list = ns.getClassDef ();
		for (ClassDef cd : list){
			classes ++;			
			if (cd.isDeferred()){			
				abstClass ++;
			}			
		}
		if (classes==abstClass){
			return 1;
		}		
		return (abstClass/(classes - abstClass));
	}
}